home *** CD-ROM | disk | FTP | other *** search
- /* VTRM -- unix-dependent tty twiddling. */
-
- #include <stdio.h>
- #ifndef TERMIO
- #include <sgtty.h>
- #else
- #include <termio.h>
- #endif TERMIO
- #include <signal.h>
-
- #include "vtrm.h"
-
- typedef char *string;
- typedef int bool;
- #define Yes 1
- #define No 0
-
- extern short ospeed; /* Defined in vtrm.c, used by termcap's tgoto/tputs. */
-
- /* tty modes */
- #ifndef TERMIO
-
- /* v7/BSD tty control */
- static struct sgttyb oldtty, newtty;
- #ifdef TIOCSETN
- /* Redefine stty to uses TIOCSETN, so type-ahead is not flushed */
- #define stty(fd, bp) ioctl(fd, TIOCSETN, (char *) bp)
- #endif
-
- #ifdef TIOCSLTC /* BSD -- local special chars, must all be turned off */
- static struct ltchars oldltchars;
- static struct ltchars newltchars= {-1, -1, -1, -1, -1, -1};
- #endif TIOCSLTC
-
- #ifdef TIOCSETC /* V7 -- standard special chars, some must be turned off too */
- static struct tchars oldtchars;
- static struct tchars newtchars;
- #endif TIOCSETC
-
- #else TERMIO
-
- /* AT&T tty control */
- static struct termio oldtty, newtty;
- #define gtty(fd,bp) ioctl(fd, TCGETA, (char *) bp)
- #define stty(fd,bp) ioctl(fd, TCSETAW, (char *) bp)
-
- #endif TERMIO
-
- static bool know_ttys = No;
-
- int
- setttymode()
- {
- if (!know_ttys) {
- if (gtty(0, &oldtty) != 0 || gtty(0, &newtty) != 0)
- return TE_NOTTY;
- #ifndef TERMIO
- ospeed = oldtty.sg_ospeed;
- #ifdef PWB
- newtty.sg_flags = (newtty.sg_flags & ~ECHO & ~CRMOD & ~XTABS)
- | RAW;
- #else PWB
- newtty.sg_flags = (newtty.sg_flags & ~ECHO & ~CRMOD & ~XTABS)
- | CBREAK;
- #endif PWB
- #ifdef TIOCSLTC
- ioctl(0, TIOCGLTC, (char *) &oldltchars);
- #endif
- #ifdef TIOCSETC
- ioctl(0, TIOCGETC, (char *) &oldtchars);
- #endif
-
- #else TERMIO
- ospeed= oldtty.c_lflag & CBAUD;
- newtty.c_iflag &= ~ICRNL; /* No CR->NL mapping on input */
- newtty.c_oflag &= ~ONLCR; /* NL doesn't output CR */
- newtty.c_lflag &= ~(ICANON|ECHO); /* No line editing, no echo */
- newtty.c_cc[VMIN]= 3; /* wait for 3 characters */
- newtty.c_cc[VTIME]= 1; /* or 0.1 sec. */
- /* Should set intrc and quitc and some others, too? */
- #endif TERMIO
- know_ttys = Yes;
- }
- stty(0, &newtty);
- #ifndef TERMIO
- #ifdef TIOCSLTC
- ioctl(0, TIOCSLTC, (char *) &newltchars);
- #endif TIOCSLTC
- #ifdef TIOCSETC
- ioctl(0, TIOCGETC, (char *) &newtchars);
- newtchars.t_intrc= -1;
- #ifdef NDEBUG
- newtchars.t_quitc= -1;
- #endif
- newtchars.t_eofc= -1;
- newtchars.t_brkc= -1;
- ioctl(0, TIOCSETC, (char *) &newtchars);
- #endif TIOCSETC
- #endif TERMIO
- return TE_OK;
- }
-
- resetttymode()
- {
- if (know_ttys) {
- stty(0, &oldtty);
- #ifndef TERMIO
- #ifdef TIOCSLTC
- ioctl(0, TIOCSLTC, (char *) &oldltchars);
- #endif TIOCSLTC
- #ifdef TIOCSETC
- ioctl(0, TIOCSETC, (char *) &oldtchars);
- #endif TIOCSETC
- #endif TERMIO
- know_ttys= No;
- }
- }
-
-
- /*
- * Return the next input character, or -1 if read fails.
- * Only the low 7 bits are returned, so reading in RAW mode is permissible
- * (although CBREAK is preferred if implemented).
- * To avoid having to peek in the input buffer for trmavail, we use the
- * 'read' system call rather than getchar().
- * (The interface allows 8-bit characters to be returned, to accomodate
- * larger character sets!)
- */
-
- static int pushback= -1;
-
- int
- trminput()
- {
- char c;
-
- if (pushback >= 0) {
- c= pushback;
- pushback= -1;
- return c;
- }
- if (read(0, &c, 1) <= 0)
- return -1;
- return c & 0177;
- }
-
- trmpushback(c)
- int c;
- {
- pushback= c;
- }
-
-
- /*
- * See if there's input available from the keyboard.
- * The code to do this is dependent on the type of Unix you have
- * (BSD, System V, ...).
- * Return value: 0 -- no input; 1 -- input; -1 -- unimplementable.
- * Note that each implementation form should first check pushback.
- *
- * TO DO:
- * - Implement it for other than 4.x BSD! (notably System 5)
- */
-
- #ifdef SELECT
-
- #include <sys/time.h>
-
- int
- trmavail()
- {
- int nfound, nfds, readfds;
- static struct timeval timeout= {0, 0};
-
- if (pushback >= 0)
- return 1;
- readfds= 1 << 0;
- nfds= 0+1;
- nfound= select(nfds, &readfds, (int*) NIL, (int*) NIL, &timeout);
- return nfound > 0;
- }
-
- #define TRMAVAIL_DEFINED
-
- #endif SELECT
-
- #if !defined(TRMAVAIL_DEFINED) && defined(FIONREAD)
-
- int
- trmavail()
- {
- long n;
-
- if (pushback >= 0)
- return 1;
- ioctl(0, FIONREAD, (char *) &n);
- return n > 0;
- }
-
- #define TRMAVAIL_DEFINED
-
- #endif FIONREAD
-
- #ifndef TRMAVAIL_DEFINED
-
- int
- trmavail()
- {
- if (pushback >= 0)
- return 1;
- return -1;
- }
-
- #endif
-
-
- /*
- * Suspend the editor.
- * Should be called only after trmend and before trmstart!
- */
-
- trmsuspend()
- {
- int (*oldsig)();
-
- oldsig= signal(SIGTSTP, SIG_IGN);
- if (oldsig == SIG_IGN)
- return; /* Could spawn a subshell here... */
- trmend(); /* Safety net */
- (void) signal(SIGTSTP, oldsig);
- kill(0, SIGSTOP);
- }
-
- /*
- * Get the true window size.
- * May return 0 if unknown.
- */
-
- gettruewinsize(plines, pcols)
- int *plines, *pcols;
- {
- #ifdef TIOCGWINSZ
- struct winsize win;
-
- if (ioctl(0, TIOCGWINSZ, (char *) &win) == 0) {
- *plines= win.ws_row;
- *pcols= win.ws_col;
- }
- else
- #endif
- *plines= *pcols= 0;
- }
-